#ifndef TDEAPPORO_H_
#define TDEAPPORO_H_
#include <iostream>
#include "tvectorporo.h"
using namespace std;

/** \file tdeapporo.h
* \brief .h de la cola
* Definicion de las clases del deap.
*/

enum THEAP {HEAP_MINIMO, HEAP_MAXIMO};

/** \class TDeapPoro
* \brief Clase TDeapPoro
* Clase completa para construir TDeapPoro
*/
class TDeapPoro{

    /** \brief Sobrecarga del operador SALIDA
    * Imprime el contenido del objeto
    * \param os Tipo ostream&
    * \param deap Objeto TDeapPoro
    * \return ostream&
    */
    friend ostream & operator<<(ostream &, const TDeapPoro &);

    
  public:
    /** \brief Constructor por defecto
    * Construye un objeto TDeapPoro con valores inicializados
    */
    TDeapPoro();
    /** \brief Constructor de copia
    * Crea una copia del objeto que recibe
    * \param dp Deap de la que copiar
    */
    TDeapPoro(const TDeapPoro &);
    /** \brief Destructor
    * Destruye el objeto liberando memoria de las variables
    */
    ~TDeapPoro();
    /** \brief Sobrecarga del operador asignación
    * Copia los valores de un objeto a otro
    * \param dp Deap del que copiar
    * \return Objeto copiado
    */
    TDeapPoro & operator=(const TDeapPoro &);

    /** \brief Sobrecarga del operador igualdad
    * Compara los dos objetos y devuelve un bool
    * \param de Cola a comparar
    * \return Devuelve si es verdadero o falso
    */
    bool operator==(const TDeapPoro &) const;
    /** \brief EsVacio()
    * Mira si el deap es vacio o no
    * \return Devuelve si es verdadero o falso
    */
    bool EsVacio() const;
    /** \brief Insertar
    * Inserta un nodo en el deap
    * \param p Poro a insertar
    * \return Devuelve si es verdadero o falso
    */
    bool Insertar(const TPoro &);
    /** \brief BorrarMax
    * Borrar el poro del deap maximo
    * \return Devuelve si es verdadero o falso
    */
    bool BorrarMax();
    /** \brief BorrarMin
    * Borrar el poro del deap minimo
    * \return Devuelve si es verdadero o falso
    */
    bool BorrarMin();
    /** \brief Max
    * Devuelve el maximo del deap
    * \return Devuelve el poro
    */
    TPoro Max() const;
    /** \brief Min
    * Devuelve el minimo del deap
    * \return Devuelve el poro
    */
    TPoro Min() const;
    /** \brief Altura
    * Devuelve la altura del deap
    * \return entero
    */
    int Altura() const;
    /** \brief Nodos
    * Devuelve la cantidad de poros en el deap
    * \return entero
    */
    int Nodos() const;
    /** \brief Inorden
    * Devuelve el recorrido inorden
    * \return vector
    */
    TVectorPoro  Inorden() const;
    /** \brief Preorden
    * Devuelve el recorrido preorden
    * \return vector
    */
    TVectorPoro  Preorden() const;
    /** \brief Postorden
    * Devuelve el recorrido postorden
    * \return vector
    */
    TVectorPoro  Postorden() const;
    /** \brief Niveles
    * Devuelve el recorrido por niveles
    * \return vector
    */
    TVectorPoro Niveles() const;

private:
    /** \brief ObtenerHeap
    * Devuelve en que heap estas
    * \param i posicion actual
    * \return theap
    */
    THEAP ObtenerHeap(int i) const;
    /** \brief ObtenerAsociadoMaximo
    * Devuelve el asociado maximo
    * \param i posicion
    * \return entero asociado
    */
    int ObtenerAsociadoMaximo(int i) const;
    /** \brief ObtenerAsociadoMinimo
    * Devuelve el asociado minimo
    * \param i posicion
    * \return entero asociado
    */
    int ObtenerAsociadoMinimo(int j) const;
    /** \brief Intercambiar
    * Intercambia las posiciones de dos nodos
    * \param i posicion
    * \param j posicion
    * \return entero
    */
    void Intercambiar(int i, int j);
    /** \brief FlotarMin
    * Hunde un nodo
    * \param i posicion
    */
    void FlotarMin(int i);
    /** \brief FlotarMax
    * Hunde un nodo
    * \param i posicion
    */
    void FlotarMax(int j);
    /** \brief InordenAux
    * Funcion auxiliar recursiva para el recorrido
    * \param vi vector
    * \param pos posicion
    * \param i padre
    */
    void InordenAux(TVectorPoro &vi, int &pos, int i) const;
    /** \brief PreordenAux
    * Funcion auxiliar recursiva para el recorrido
    * \param vi vector
    * \param pos posicion
    * \param i padre
    */
    void PreordenAux(TVectorPoro &vi, int &pos, int i) const;
    /** \brief PostordenAux
    * Funcion auxiliar recursiva para el recorrido
    * \param vi vector
    * \param pos posicion
    * \param i padre
    */
    void PostordenAux(TVectorPoro &vi, int &pos, int i) const;
    /** \brief Buscar
    * Auxiliar para buscar el poro en el deap
    * \param p poro
    * \return Devuelve si esta o no esta en el deap
    */
    bool Buscar(const TPoro &p);
    /** \brief v
    *	Variable que representa el vector del deap
    */
    TVectorPoro v;
    /** \brief posicion
    *	Variable que representa el la siguiente posicion libre del deap
    */
    int posicion;

};

#endif /*TDEAPPORO_H_*/
